package com.wing.cabinet.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wing.cabinet.dao.CabinetLoadPlanDao;
import com.wing.cabinet.model.entity.CabinetLoadPlan;
import com.wing.cabinet.model.entity.CabinetLoadPlanDetail;
import com.wing.cabinet.model.request.CabinetLoadPlanDetailForm;
import com.wing.cabinet.model.request.CabinetLoadPlanForm;
import com.wing.cabinet.model.response.CabinetLoadPlanDetailVO;
import com.wing.cabinet.model.response.CabinetLoadPlanVO;
import com.wing.common.exception.BusinessException;
import com.wing.common.utils.JsonResult;
import com.wing.common.utils.Result;
import com.wing.enterprise.feign.EnterpriseClient;
import com.wing.enterprise.product.model.response.ProductPackLabelVO;
import com.wing.order.model.entity.DistributionDemand;
import com.wing.order.model.entity.InventoryJobLabel;
import com.wing.order.model.entity.InventoryOutPlan;
import com.wing.order.model.entity.InventoryOutPlanDetail;
import com.wing.order.model.request.InventoryOutPlanDetailForm;
import com.wing.order.model.request.InventoryOutPlanForm;
import com.wing.order.model.response.DistributionDemandDetailVO;
import com.wing.order.model.response.DistributionDemandVO;
import com.wing.order.model.response.InventoryJobLabelVO;
import com.wing.order.service.DistributionDemandService;
import com.wing.order.service.InventoryJobLabelService;
import com.wing.order.service.InventoryOutPlanDetailService;
import com.wing.order.service.InventoryOutPlanService;
import com.wing.product.model.entity.ProductDetail;
import com.wing.product.model.response.ProductDetailVO;
import com.wing.product.service.ProductDetailService;
import com.wing.warehouse.model.entity.WarehouseInventoryType;
import com.wing.warehouse.service.WarehouseInventoryTypeService;
import com.wing.web.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 上货计划-ServiceImpl
 *
 * @author
 */
@Service
@Slf4j
public class CabinetLoadPlanServiceImpl extends ServiceImpl<CabinetLoadPlanDao, CabinetLoadPlan> implements CabinetLoadPlanService {

    @Autowired
    private CabinetLoadPlanDetailService cabinetLoadPlanDetailService;
    @Autowired
    private InventoryOutPlanService inventoryOutPlanService;
    @Autowired
    private InventoryOutPlanDetailService inventoryOutPlanDetailService;
    @Autowired
    private WarehouseInventoryTypeService warehouseInventoryTypeService;
    @Autowired
    private ProductDetailService productDetailService;
    @Autowired
    private DistributionDemandService distributionDemandService;

    @Autowired
    private EnterpriseClient enterpriseClient;

    @Autowired
    private InventoryJobLabelService inventoryJobLabelService;

    @Override
    @Transactional(readOnly = false)
    public int add(CabinetLoadPlanForm cabinetLoadPlanForm) {
        //校验
        CabinetLoadPlan cabinetLoadPlan =new CabinetLoadPlan();
        CopyOptions copyOptions = CopyOptions.create()
        .setEditable(CabinetLoadPlan.class)
        .setIgnoreError(true)
        .setIgnoreNullValue(true);
        BeanUtil.copyProperties(cabinetLoadPlanForm, cabinetLoadPlan, copyOptions);
        SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
        if(cabinetLoadPlan.getType().equals(CabinetLoadPlan.Type.replenishment)){
            cabinetLoadPlan.setCode("BHSH-"+sf.format(new Date()));
            if(null == cabinetLoadPlanForm.getDistributionDemandId()){
                throw new BusinessException(300, "请选择配货需求订单");
            }
        }else{
            cabinetLoadPlan.setCode("ZZSH-"+sf.format(new Date()));
            if(null == cabinetLoadPlanForm.getCabinetId()){
                throw new BusinessException(300, "请选择刀柜");
            }
        }
        if(null == cabinetLoadPlan.getWarehouseId()){
            throw new BusinessException(300, "请选择领货仓库");
        }
        cabinetLoadPlan.setCreator(JwtUtils.getLoginUserId());
        cabinetLoadPlan.setCreatorName(JwtUtils.getLoginUsername());
        int i = baseMapper.insert(cabinetLoadPlan);
        if(i > 0){
            List<CabinetLoadPlanDetail> cabinetLoadPlanDetails = new ArrayList<>();
            if(cabinetLoadPlanForm.getCabinetLoadPlanDetailForms().size() > 0){
                for (CabinetLoadPlanDetailForm cabinetLoadPlanDetailForm : cabinetLoadPlanForm.getCabinetLoadPlanDetailForms()) {
                    //校验
                    CabinetLoadPlanDetail cabinetLoadPlanDetail =new CabinetLoadPlanDetail();
                    copyOptions = CopyOptions.create()
                            .setEditable(CabinetLoadPlanDetail.class)
                            .setIgnoreError(true)
                            .setIgnoreNullValue(true);
                    BeanUtil.copyProperties(cabinetLoadPlanDetailForm, cabinetLoadPlanDetail, copyOptions);
                    cabinetLoadPlanDetail.setCreator(JwtUtils.getLoginUserId());
                    cabinetLoadPlanDetail.setCreatorName(JwtUtils.getLoginUsername());
                    cabinetLoadPlanDetail.setCabinetLoadPlanId(cabinetLoadPlan.getId());
                    cabinetLoadPlanDetails.add(cabinetLoadPlanDetail);
                }
                boolean isSave = cabinetLoadPlanDetailService.saveBatch(cabinetLoadPlanDetails);
                if(!isSave){
                    throw new BusinessException(300, "参数错误");
                }
            }else{
                throw new BusinessException(300, "请补充上货明细数据");
            }
        }
        return i;
    }

    @Override
    public List<CabinetLoadPlanVO> list4app(Map<String, Object> params) {
        return baseMapper.list4app(params);
    }

    @Override
    public Page<CabinetLoadPlanVO> pageList4app(Page page, Map<String, Object> params) {
        List<CabinetLoadPlanVO> list = baseMapper.list4app(page, params);
        page.setRecords(list);
        return page;
    }

    @Override
    public CabinetLoadPlanVO get4appById(Long id) {
        return baseMapper.get4appById(id);
    }

    @Override
    @Transactional(readOnly = false)
    public int audit(CabinetLoadPlan cabinetLoadPlan) {
        int i = baseMapper.updateById(cabinetLoadPlan);
        if(i > 0){
            if(cabinetLoadPlan.getStatus().equals(CabinetLoadPlan.Status.pass)){ // 审核通过
                // 生成出库单计划
                InventoryOutPlanForm inventoryOutPlanForm = new InventoryOutPlanForm();
                inventoryOutPlanForm.setCreator(JwtUtils.getLoginUserId());
                inventoryOutPlanForm.setCreatorName(JwtUtils.getLoginUsername());
                // 查询出入库类型为调拨 出库，编码为 shippingPlan
                WarehouseInventoryType warehouseInventoryType = warehouseInventoryTypeService.getOne(new QueryWrapper<WarehouseInventoryType>()
                        .eq("operate_type", WarehouseInventoryType.OperateType.transfer)
                        .eq("inventory_type", WarehouseInventoryType.InventoryType.out)
                        .eq("code", "shippingPlan"));
                if(warehouseInventoryType == null){
                    throw new BusinessException(300, "请添加上货计划相关出入库类型");
                }
                inventoryOutPlanForm.setInoutTypeCode(warehouseInventoryType.getCode());
                inventoryOutPlanForm.setInoutTypeId(warehouseInventoryType.getId()); // 出入库类型id
//                inventoryOutPlanForm.setInWarehouseId(cabinetLoadPlan.getWarehouseId()); // 目标仓库id
                inventoryOutPlanForm.setCabId(cabinetLoadPlan.getCabinetId());
                inventoryOutPlanForm.setOutWarehouseId(cabinetLoadPlan.getWarehouseId()); // 发货仓库id
                inventoryOutPlanForm.setRemark("上货计划("+cabinetLoadPlan.getCode()+")审核通过后生成出库单计划");
                inventoryOutPlanForm.setStatus(InventoryOutPlan.Status.confirm); // 已审核
                inventoryOutPlanForm.setCabinetLoadPlanId(cabinetLoadPlan.getId()); // 上货计划ID
                List<CabinetLoadPlanDetail> cabinetLoadPlanDetails = cabinetLoadPlanDetailService.list(new QueryWrapper<CabinetLoadPlanDetail>().eq("cabinet_load_plan_id", cabinetLoadPlan.getId()));
                cabinetLoadPlanDetails=combine(cabinetLoadPlanDetails);
                List<InventoryOutPlanDetailForm> inventoryOutPlanDetailForms = new ArrayList<>();
                for (CabinetLoadPlanDetail cabinetLoadPlanDetail : cabinetLoadPlanDetails) {
                    // 出库单计划明细
                    InventoryOutPlanDetailForm inventoryOutPlanDetailForm = new InventoryOutPlanDetailForm();
                    inventoryOutPlanDetailForm.setCreator(JwtUtils.getLoginUserId());
                    inventoryOutPlanDetailForm.setCreatorName(JwtUtils.getLoginUsername());
                    inventoryOutPlanDetailForm.setSkuCode(cabinetLoadPlanDetail.getSkuCode());
                    ProductDetailVO productDetailVO = productDetailService.getProductInfoBySkuCode(cabinetLoadPlanDetail.getSkuCode());
                    if(productDetailVO == null){
                        throw new BusinessException(300, "参数错误");
                    }
                    inventoryOutPlanDetailForm.setSkuPic(productDetailVO.getProductPic());
                    inventoryOutPlanDetailForm.setProductName(productDetailVO.getProductName());
                    inventoryOutPlanDetailForm.setSkuSpecCode(productDetailVO.getSkuSpecValueNames());
                    inventoryOutPlanDetailForm.setUnitName(productDetailVO.getUnitName());
                    inventoryOutPlanDetailForm.setQuantity(Long.parseLong(cabinetLoadPlanDetail.getQuantity().toString()));
                    inventoryOutPlanDetailForm.setEnterpriceCode(productDetailVO.getEnterpriceCode());
                    inventoryOutPlanDetailForm.setBarcode(productDetailVO.getBarcode());
                    inventoryOutPlanDetailForm.setSupplyPrice(null != productDetailVO.getSupplyPrice() ? productDetailVO.getSupplyPrice() : BigDecimal.ONE);
                    inventoryOutPlanDetailForm.setMarketPrice(null != productDetailVO.getMarketPrice() ? productDetailVO.getMarketPrice() : BigDecimal.ONE);
                    inventoryOutPlanDetailForms.add(inventoryOutPlanDetailForm);
                }
                inventoryOutPlanForm.setProductJson(JSON.toJSONString(inventoryOutPlanDetailForms)); // 出库单计划明细
                inventoryOutPlanService.add(inventoryOutPlanForm);
            }
        }
        return i;
    }

    private List<CabinetLoadPlanDetail> combine(List<CabinetLoadPlanDetail> list){
        List<CabinetLoadPlanDetail> resultList=new ArrayList<>();
        Map<String,CabinetLoadPlanDetail> map=new HashMap();
        for (CabinetLoadPlanDetail cabinetLoadPlanDetail:list){
            String key=cabinetLoadPlanDetail.getSkuCode();
            CabinetLoadPlanDetail cabinetLoadPlanDetail2=map.get(key);
            if (cabinetLoadPlanDetail2==null){
                cabinetLoadPlanDetail2=cabinetLoadPlanDetail;
                map.put(key,cabinetLoadPlanDetail2);
            }else{
                cabinetLoadPlanDetail2.setQuantity(cabinetLoadPlanDetail2.getQuantity()+cabinetLoadPlanDetail.getQuantity());
            }
        }
        map.keySet().forEach(item->{
            resultList.add(map.get(item));
        });
        return resultList;
    }


    @Override
    public JsonResult<ProductPackLabelVO> getReceivePackLabel(Long id, String labelCode) {
        CabinetLoadPlanVO loadPlanVo = baseMapper.get4appById(id);
        if (loadPlanVo == null) {
            return JsonResult.fail("未找到上货计划业务数据");
        }
        JsonResult<ProductPackLabelVO> jsonResult = enterpriseClient.getLabelByCode(labelCode);
        if (JsonResult.Code.SUCCESS.getCode()!=jsonResult.getCode()){
            return jsonResult;
        }
        ProductPackLabelVO labels = jsonResult.getData();
        if (labels == null) {
            return JsonResult.fail("未找到包装条码数据");
        }
        Map paramMap=new HashMap();
        paramMap.put("packLabelCode",labelCode);
        paramMap.put("loadPlanId",id);
        List<InventoryJobLabelVO> labelVOS=inventoryJobLabelService.list4app(paramMap);
        if (labelVOS.size()==0){
            throw new BusinessException("未找到此上货计划已出库的包装条码");
        }
        InventoryJobLabelVO jobLabelVO=null;
        for (InventoryJobLabelVO inventoryJobLabelVO:labelVOS){
            if (inventoryJobLabelVO.getPackLabeCode().equals(labelCode)){
                if (InventoryJobLabel.Status.receive.equals(inventoryJobLabelVO.getStatus())){
                    throw new BusinessException("此包装条码已领货");
                }
                if (!InventoryJobLabel.Status.inventoryOut.equals(inventoryJobLabelVO.getStatus())){
                    throw new BusinessException("未找到此上货计划已出库的包装条码");
                }
                jobLabelVO=inventoryJobLabelVO;
            }
        }
        paramMap = new HashMap();
        paramMap.put("cabinetLoadPlanId", id);
        paramMap.put("type",loadPlanVo.getType().name());
        List<CabinetLoadPlanDetailVO> loadPlanDetails = cabinetLoadPlanDetailService.list4app(paramMap);
        if (loadPlanDetails.size() == 0) {
            return JsonResult.fail("未找到此上货计划单的业务明细数据");
        }
        StringBuffer skuCodes = new StringBuffer();
        Map<String, CabinetLoadPlanDetailVO> loadPlaneDetailIdMap = new HashMap<>();
        loadPlanDetails.forEach(item -> {
            skuCodes.append(item.getSkuCode() + ",");
            loadPlaneDetailIdMap.put(item.getSkuCode(), item);
        });
        if (!skuCodes.toString().contains(labels.getSkuCode())) {
            return JsonResult.fail("此包装编码的产品SKU[" + labels.getSkuCode() + "]不属于该上货计划含有的产品SKU[" + skuCodes.toString().substring(0, skuCodes.toString().length() - 1) + "]");
        }
        labels.setPackLabelId(labels.getId());
        labels.setId(jobLabelVO.getId());
        labels.setDemandDetailId(loadPlaneDetailIdMap.get(labels.getSkuCode()).getDistributionDemandDetailId());
        labels.setDemandId(loadPlaneDetailIdMap.get(labels.getSkuCode()).getDistributionDemandId());
        labels.setLoadPlanId(id);
        labels.setLoadPlanDetailId(loadPlaneDetailIdMap.get(labels.getSkuCode()).getId());
//        labels.setQuantityReceive(loadPlaneDetailIdMap.get(labels.getSkuCode()).getQuantityReceive());
//        labels.setQuantityConfirm(loadPlaneDetailIdMap.get(labels.getSkuCode()).getQuantityConfirm().intValue());
        labels.setDemandCode(loadPlanVo.getDistCode());
        labels.setSkuPic(loadPlaneDetailIdMap.get(labels.getSkuCode()).getSkuPic());
        labels.setSkuName(loadPlaneDetailIdMap.get(labels.getSkuCode()).getSkuName());
        labels.setSkuSpec(loadPlaneDetailIdMap.get(labels.getSkuCode()).getSkuSpecValueNames());
        labels.setMarketPrice(loadPlaneDetailIdMap.get(labels.getSkuCode()).getMarketPrice());
        labels.setProductTypeName(loadPlaneDetailIdMap.get(labels.getSkuCode()).getProductTypeName());
        labels.setProductCategoryName(loadPlaneDetailIdMap.get(labels.getSkuCode()).getProductCategoryName());
        labels.setProductBrandName(loadPlaneDetailIdMap.get(labels.getSkuCode()).getProductBrandName());
        labels.setUnitName(loadPlaneDetailIdMap.get(labels.getSkuCode()).getUnitName());
        if (labels.getSurplusQuantity() == 0) {
            return JsonResult.fail("此包装条码已领货出库");
        }
        return JsonResult.success(labels);

    }
}
